package Models;

import DB.DBLocation;
import DB.DBRoute;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

public class Route implements DB.RowInterface
{
	private int routeNo;
	private ArrayList<Location> locations = new ArrayList<Location>();

	public Route()
	{}

	public void importData(ResultSet data) throws SQLException
	{
		this.setRouteNo(data.getInt("routeNo"));
		fetchSubItems();
	}
	
	public void fetchSubItems()
	{
		DBLocation dbl = new DBLocation();
		ArrayList<Location> locationRows = dbl.fetchAll("routeNo = "+getRouteNo(), "zipCode ASC");
		if(locationRows == null) locationRows = new ArrayList<Location>();
		this.setLocations(locationRows);
	}

	public HashMap exportData()
	{
		HashMap data = new HashMap();
		return data;
	}

	public void refreshData()
	{
		Route route = new DBRoute().fetchByNo(getRouteNo());
		this.setLocations(route.getLocations());
	}

	public static String[] getSearchColumns()
	{
		return new String[] { "routeNo" };
	}

	public double getTotalDistance()
	{
		Checkpoint c1 = null, c2 = null;
		double distance = 0;

		for(Location location : getLocations())
		{
			if(c1 == null)
			{
				c1 = location.getCheckpoint();
			}
			else
			{
				c2 = location.getCheckpoint();
			}
			if(c1 != null && c2 != null)
			{
				distance += calculateDistance(c1, c2);
			}
		}
		
		return distance*100;
	}

	public double getTotalTime()
	{
		double time = getTotalDistance();

		for(Location location : getLocations())
		{
			location.fetchSubItems();
			time += 3;

			for(Round round : location.getRounds())
			{
				round.fetchSubItems();
				time += round.getTime();
			}
		}
		
		return time;
	}

	public String getTotalTimeToString()
	{
		double time = getTotalTime();
//		System.out.println("Total time: "+time);
		double seconds = time-(int)time;
//		System.out.println("Seconds: "+seconds);
		seconds = seconds*60;
//		System.out.println("Seconds * 60: "+seconds);
		int minutes = (int)time+(int)seconds;
//		System.out.println("Minutes: "+minutes);
		seconds = Math.ceil(seconds*100);
		String secondsS = String.valueOf(seconds);
		if(secondsS.length() == 1) secondsS = secondsS+"01";
//		System.out.println("Seconds * 100 + floor'ed: "+seconds);
		String timeS = minutes+":"+secondsS;
//		System.out.println("Time as string: "+timeS);
		return timeS.substring(0, timeS.indexOf(":")+2);
	}

	private double calculateDistance(Checkpoint c1, Checkpoint c2)
	{
		double x = Math.pow(c2.getLongitude()-c1.getLongitude(), 2);
		double y = Math.pow(c2.getLatitude()-c1.getLatitude(), 2);
		return Math.sqrt(x+y);
	}

	public boolean addLocation(Location location)
	{
		location.setRouteNo(getRouteNo());
		return this.locations.add(location);
	}

	public boolean removeLocation(Location location)
	{
		int i = 0;
		while(i <= getLocations().size())
		{
			if(location.getLocationNo() == getLocations().get(i).getLocationNo())
			{
				location.setRouteNo(0);
				new DBLocation().update(location.exportData(), "locationNo = "+location.getLocationNo());
				return locations.remove(getLocations().get(i));
			}
			i++;
		}
		return false;
	}

	public void setRouteNoOnLocations()
	{
		for(Location locationE : locations)
		{
			locationE.setRouteNo(routeNo);
		}
	}

	public ArrayList<Location> getLocations()
	{
		return locations;
	}

	public void setLocations(ArrayList<Location> locations)
	{
		this.locations = locations;
	}

	public int getRouteNo()
	{
		return routeNo;
	}

	public void setRouteNo(int routeNo)
	{
		this.routeNo = routeNo;
	}
}